/**
 * 基于Layui 的React Form组件
 */
let commList;
let updateList=[];
let gettingData = false;
function registerUpdate(func) {
    updateList.push(func);
}

/**
 * 控件包含5个Select组件，小区，楼栋，单元，楼层，房间
 * 可通过属性参数动态调整显示的控件个数
 *
 * 数据操作:
 *
 * ref.commCode 读写小区控件的编号
 * ref.commText 读小区名
 * ref.buildingCode 读写楼栋数
 * ref.buildingText 读取楼栋别名
 * ref.unitCode  读写单元数
 * ref.unitText  读单元别名
 * ref.floorCode 读写楼层数
 * ref.roomCode 读写房间号
 *
 * props:
 * @mask : 数组类型，传入building,unit,floor,room, 传入的都会被屏蔽
 *         小区没有mask属性, 但小区的显示，依赖于楼栋控件和小区数目
 *         1.假如小区数为1, 且building没有被mask, 那么小区控件自动隐藏
 *         2.假如小区数为1, 且building被mask,那么小区控件不会隐藏，但不会显示select，会变成一个label
 *
 * @commSelectShowStyle : 不传 在只有一个小区时,会隐藏小区选择控件
 *                        BadgeWhenOneComm   当此控件只显示小区选择器且当前帐号只有一个小区, 则显示一个Badge文字，而不是select
 *                        ShowWhenOneComm    当只有一个小区时, 也显示小区选择控件
 *
 * @firstValue          : 在有(多个)小区时，第一个select项是否为空,假如设置此属性, 则firstValue会被设置成第一项，否则默认为第一个小区
 *
 * @formLabelName       : 假如控件在Form控件下,则可以内置一个Label,这样Label可以与commSelect一起自动隐藏
 * @onChangeComm        : 小区选择回调
 * @onChangeBuilding    : 楼栋选择回调
 * @onChangeUnit        : 单元选择回调
 * @onChangeFloor       : 楼层选择回调
 * @onChangeRoom        : 房号选择回调
 */
class LayuiCommSelect extends React.Component {
    constructor(props){
        super(props);
        this.mask = {};
        if(props.mask){
            for(let i=0;i<props.mask.length;i++){
                this.mask[props.mask[i]] = true;
            }
        }

        this.state = {
            commList:[],
            buildings:{},
            units:{},
            floors:{},
            rooms:[]
        }

        let {mask,value,...otherProps} = this.props;
        this.otherProps = otherProps;
        if(props['lay-verify'])
            this.otherProps['lay-verify'] = props['lay-verify'];
    }


    updateState(stateName,commCode,buildingCode,unitCode){
        let params = {commCode:commCode};
        if(stateName == 'units')
            params.buildingCode = buildingCode;
        else if(stateName == 'floors'){
            params.buildingCode = buildingCode;
            params.unitCode = unitCode;
        }
        let newState = {};
        newState[stateName] = {};
        this.setState(newState);

        postJsonNotLayuiLoad("/BuildingsCtrl/getBuidingsInfoProcessed.x",params,(data)=>{
            newState[stateName] = data.data;
            this.setState(newState);
        })

    }

    execUpdate(data){
        if(data)
            commList = data.data;
        if(!commList)
            return;
        for(let i=0;i<updateList.length;i++) {
            updateList[i]();
        }
        updateList = [];
    }

    componentDidMount(){

        registerUpdate(()=>{
            let initComm = this.props.commCode?this.props.commCode:(this.props.firstValue?"":commList[0].commCode);
            this.commChange(initComm);
            if (commList.length == 1) {
                this.mask.commCode = true;
            }

            this.setState({commList: commList});
        })

        if(!gettingData) {
            gettingData = true;
            postJsonNotLayuiLoad("/comm/findCommList.x", null, (data) => {
                this.execUpdate(data);
            })
        }else
            this.execUpdate();
    }

    componentWillReceiveProps(newProps){

        if(newProps.commCode && newProps.commCode !== this.commCodeBak){
            this.commChange(newProps.commCode);
        }

    }

    /**
     * 从小区列表中获取对应小区的名称，假如没有找到且不为空，则返回false
     * @param commCode
     * @returns {boolean}
     */
    getCommNameFromCommCode(commCode){
        for(let i=0;i<commList.length;i++){
            if(commList[i].commCode == commCode) {
                return commList[i].commName;
            }
        }

        return !commCode;
    }

    commChange(comm){
        this.commTextBak = this.getCommNameFromCommCode(comm);
        if(this.commTextBak)
            this.commCodeBak = comm;
        else {
            console.log("invalid comm "+comm);
            return;
        }
        if(!this.mask.building) {
            this.updateState('buildings', comm);
        }
        if(this.props.onChangeComm) {
            this.props.onChangeComm(comm);
        }
    }

    buildingChange(building){
        if(!this.mask.unit) {
            this.updateState('units', this.commCodeBak, building);
        }
        if(this.props.onChangeBuilding)
            this.props.onChangeBuilding(building);
    }

    unitChange(unit){
        if(!this.mask.floor)
            this.updateState('floors',this.commCodeBak,this.refs.buildingSelect.value,unit);
        if(this.props.onChangeUnit)
            this.props.onChangeUnit(unit);
    }

    floorChange(floor){
        if(!this.mask.room)
            this.setState({rooms:this.state.floors.floors[floor]});
        if(this.props.onChangeFloor)
            this.props.onChangeFloor(floor);
    }

    roomChange(room){
        if(this.props.onChangeRoom)
            this.props.onChangeRoom(room);
    }

    /**
     * 在只有一个小区的情况下，假如楼栋选择器存在,则自动隐藏小区选择器,假如楼栋选在器不存在，则显示一个label,不再显示select
     * @returns {*}
     */
    getComms(){
        if(this.mask.commCode && this.props.commSelectShowStyle == "BadgeWhenOneComm"){
            return <span className="layui-badge layui-bg-green" style={{fontSize:14}}>{this.commTextBak}</span>
        }
        else if(this.mask.commCode && this.props.commSelectShowStyle != "ShowWhenOneComm" && !this.props.firstValue)
            return ''
        else{
            return (
            <Select onChange={(data) => this.commChange(data)} ref="commSelect" {...this.otherProps} value={this.props.commCode}>
                {this.props.firstValue?<option value="">{this.props.firstValue}</option>:''}
                {
                    this.state.commList.length > 0 ? this.state.commList.map((comm) => {
                        return <option value={comm.commCode} data-commname={comm.commName}>{'【' + comm.commCode + '】' + comm.commName}</option>
                    }) : ''
                }
            </Select>
            )
        }

    }

    getFloors(){
        let floorArray = [];
        if(this.state.floors.floors) {
            let floorsKeys = Object.keys(this.state.floors.floors).sort();
            for (let floor in floorsKeys) {
                floorArray.push(<option
                    value={floorsKeys[floor]}>{floorsKeys[floor] + '楼'}</option>);
            }
        }
        return floorArray;
    }

    /**
     * get set接口集,获取每个select的value和text
     */
    get commCode(){
        return this.commCodeBak;
    }

    get commName(){
        return this.props.commCode?this.getCommNameFromCommCode(this.props.commCode):this.commTextBak;
    }

    get commCount(){
        return commList.length;
    }

    set commCode(value){
        this.commCodeBak = value;
        if(!this.mask.commCode)
            this.refs.commSelect.value = value;
    }

    get commText(){
        return this.props.commCode?this.getCommNameFromCommCode(this.props.commCode):this.commTextBak;
    }

    get buildingCode(){
        return this.refs.buildingSelect.value;
    }

    set buildingCode(value){
        this.refs.buildingSelect.value = value;
    }

    get buildingText(){
        return this.refs.buildingSelect.text;
    }

    get unitCode(){
        return this.refs.unitSelect.value;
    }

    set unitCode(value){
        this.refs.unitSelect.value = value;
    }

    get unitText(){
        return this.refs.unitSelect.text;
    }

    get floorCode(){
        return this.refs.floorSelect.value;
    }

    set floorCode(value){
        this.refs.floorCode.value = value;
    }

    get roomCode(){
        return this.refs.roomSelect.value;
    }

    set roomCode(value){
        this.refs.roomCode.value = value;
    }

    render(){
        return (
            [
                !this.props.formLabelName || (this.mask.commCode && this.mask.building)?'':
                <Label>{this.props.formLabelName}</Label>,
                this.getComms(),
                this.mask.building?'':
                <Select onChange={(data)=>this.buildingChange(data)} ref="buildingSelect" {...this.otherProps} value={this.props.buildingCode}>
                    {
                        this.props.buildingCode && !this.state.buildings.buildings?
                        <option value={this.props.buildingCode}>{this.props.buildingText}</option>:
                        <option value="">请选择楼栋</option>
                    }

                    {
                        this.state.buildings.buildings?this.state.buildings.buildings.map((building,index)=>{
                            return <option value={building}>{this.state.buildings.buildingsAliasName[index]}</option>
                        }):''
                    }
                </Select>,
                this.mask.unit?'':
                <Select onChange={(data)=>this.unitChange(data)} ref="unitSelect" {...this.otherProps} value={this.props.unitCode}>
                    {
                        this.props.unitCode && this.props.unitText && !this.state.units.units?
                        <option value={this.props.unitCode}>{this.props.unitText}</option>:
                        <option value="">请选择单元</option>
                    }

                    {
                        this.state.units.units?this.state.units.units.map((unit,index)=>{
                            return <option value={unit}>{this.state.units.unitAlias[index]}</option>
                        }):''
                    }
                </Select>,
                this.mask.floor?'':
                <Select onChange={(data)=>this.floorChange(data)} ref="floorSelect" {...this.otherProps} value={this.props.floorCode}>
                    {
                        this.props.floorCode && !this.state.floors.floors?
                        <option value={this.props.floorCode}>{this.props.floorCode + '楼'}</option>:
                        <option value="">请选择楼层</option>
                    }

                    {
                        this.getFloors()
                    }
                </Select>,
                this.mask.room?'':
                <Select onChange={(data)=>this.roomChange(data)} ref="roomSelect" {...this.otherProps} value={this.props.roomCode}>
                    {this.props.roomCode && this.state.rooms.length === 0?
                        <option value={this.props.roomCode}>{this.props.roomCode + '房'}</option>:
                        <option value="">请选择房间</option>
                    }

                    {
                        this.state.rooms.length>0?this.state.rooms.map((room)=>{
                            return <option value={room}>{room +'房'}</option>
                        }):''
                    }
                </Select>,
            ]
        )
    }
}